// 日期格式化 yyyy-MM-dd hh:mm:ss
export function dateFormat(date, format = 'yyyy-MM-dd hh:mm:ss') {
	if (!date) {
		return ''
	}
	if (typeof date === 'number') {
		date = new Date(date)
	}
	const o = {
		'M+': date.getMonth() + 1,
		'd+': date.getDate(),
		'h+': date.getHours(),
		'm+': date.getMinutes(),
		's+': date.getSeconds(),
		'q+': Math.floor((date.getMonth() + 3) / 3),
		S: date.getMilliseconds(),
		w: '日一二三四五六'.charAt(date.getDay())
	}
	format = format.replace(/y{4}/, date.getFullYear()).replace(/y{2}/, date.getFullYear().toString().substring(2))
	for (const k in o) {
		const reg = new RegExp(k)
		format = format.replace(reg, function (m) {
			return m.length === 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length)
		})
	}

	return format
}

export const isArray = (o) => {
	return Array.isArray(o)
}
export const isObject = (o) => {
	return Object.prototype.toString.call(o) === '[object Object]'
}
export const isString = (o) => {
	return typeof o === 'string'
}
export const isNumber = (o) => {
	return typeof o === 'number' && !isNaN(o)
}

/**
 * 判断是否为合法的日期对象
 * @param {Date} date
 * @return {Boolean}
 */
export const isValidDate = (date) => {
	return date instanceof Date && !isNaN(date.getTime())
}
/**
 * 根据日期对象获取年月日时分秒
 * @param {Date} date
 * @return {Array}
 */
export const getMetaDate = (date) => {
	if (!isValidDate(date)) {
		throw new Error(date + ' is not a valid param')
	}
	const year = date.getFullYear()
	const month = `0${date.getMonth() + 1}`.substr(-2)
	const day = `0${date.getDate()}`.substr(-2)
	const hour = `0${date.getHours()}`.substr(-2)
	const min = `0${date.getMinutes()}`.substr(-2)
	const sec = `0${date.getSeconds()}`.substr(-2)
	return [year, month, day, hour, min, sec]
}
/**
 * 计算n天前的日期
 * @param {Date} date
 * @return {Date}
 */
export const getDateBefore = (n, date = new Date()) => {
	if (!isValidDate(date)) {
		throw new Error(date + ' is not a valid param')
	}
	return new Date(date.getTime() - n * 24 * 60 * 60 * 1000)
}
/**
 * 根据后台返回的时间数据，转换成“年-月-日 时:分”的形式
 * @param {Number / Date} time
 * @param {String} formatStr
 * @return {String}
 */
export const formatTime = (time, formatStr = 'YYYY-MM-DD HH:mm:ss') => {
	const t = typeof time === 'number' ? new Date(time) : time
	if (!isValidDate(t)) {
		throw new Error(t + ' is not a valid param')
	}
	const metaDate = getMetaDate(t)
	return formatStr.replace(/Y{2,4}|M{2}|D{2}|H{2}|m{2}|s{2}/g, (match) => {
		switch (match) {
			case 'YY':
				return String(metaDate[0]).slice(-2)
			case 'YYY':
			case 'YYYY':
				return String(metaDate[0])
			case 'MM':
				return String(metaDate[1])
			case 'DD':
				return String(metaDate[2])
			case 'HH':
				return String(metaDate[3])
			case 'mm':
				return String(metaDate[4])
			case 'ss':
				return String(metaDate[5])
		}
	})
}

/**
 * 生成最近n个月的时间列表
 * defineTimeList(3) => ["2019-12-13", "2019-11-13", "2019-10-13"]
 * defineTimeList(3, 'YYYY年MM月DD日') => ["2019年12月13日", "2019年11月13日", "2019年10月13日"]
 * defineTimeList([1,2,3,6,12], 'YYYY年MM月DD日') => ["2019年11月13日", "2019年10月13日", "2019年9月13日"...]
 * defineTimeList([1,2,3,6,12], {date:'YYYY-MM-DD', date_desc: 'YYYY年MM月DD日'}) => [{date:"2019-12-13", date_desc:"2019年11月13日"},...]
 * @param {Number || Array} n
 * @param {String || Object} reg
 * @return {Array}
 */
export const newDefineTimeList = (n = 3, reg) => {
	const d = new Date()
	let dateList = []
	let returnList = []
	if (isNumber(n)) {
		dateList = Array.from({ length: n }).map((item, i) => {
			const m = new Date(d)
			m.setMonth(d.getMonth() - i)
			return m
		})
	} else if (isArray(n)) {
		dateList = n.map((item) => {
			const m = new Date(d)
			m.setMonth(d.getMonth() - item)
			return m
		})
	} else {
		throw new Error(n + ' is not a valid param')
	}

	if (!reg) reg = 'YYYY-MM-DD'
	if (isString(reg)) {
		returnList = dateList.map((item) => {
			return formatTime(item, reg)
		})
	} else if (isObject(reg)) {
		const keys = Object.keys(reg)
		returnList = dateList.map((date) => {
			const o = {}
			keys.forEach((key) => {
				o[key] = formatTime(date, reg[key])
			})
			return o
		})
	} else {
		throw new Error(reg + ' is not a valid param')
	}
	return returnList
}
/**
 * 计算两日期间隔时间是否在范围内
 * @param {Date, String} startDate
 * @param {Date, String} endDate
 * @param {Number} dayLen
 */
export const inDateRange = (startDate = new Date(), endDate, dayLen) => {
	const stDate = new Date(startDate)
	const edDate = new Date(endDate)
	if (!isValidDate(stDate) || !isValidDate(edDate)) {
		throw new Error('startDate or endDate is not a valid param')
	}
	const range = dayLen * 24 * 60 * 60 * 1000
	const stTime = stDate.getTime()
	const edTime = edDate.getTime()
	return Math.abs(edTime - stTime) <= Math.abs(range)
}

/**
 * 日期返回格式 YY年MM月
 * @param {Date, String} v // 时间选择器选中时间
 */
export const formatterMonth = (v) => {
	if (!v) {
		return ''
	}
	const dt = new Date(v)
	const td = new Date()
	const dobj = {
		y: dt.getFullYear(),
		m: dt.getMonth() + 1
	}
	const tobj = {
		y: td.getFullYear(),
		m: td.getMonth() + 1
	}
	if (dobj.y === tobj.y && dobj.m === tobj.m) {
		return '本月'
	}
	return `${dobj.y}年${dobj.m}月`
}
